home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / groff108.lha / groff-1.08 / eqn / limit.cc < prev    next >
C/C++ Source or Header  |  1992-08-03  |  5KB  |  196 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.com)
  4.  
  5. This file is part of groff.
  6.  
  7. groff is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 2, or (at your option) any later
  10. version.
  11.  
  12. groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License along
  18. with groff; see the file COPYING.  If not, write to the Free Software
  19. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include "eqn.h"
  22. #include "pbox.h"
  23.  
  24. class limit_box : public box {
  25. private:
  26.   box *p;
  27.   box *from;
  28.   box *to;
  29. public:
  30.   limit_box(box *, box *, box *);
  31.   ~limit_box();
  32.   int compute_metrics(int);
  33.   void output();
  34.   void debug_print();
  35.   void check_tabs(int);
  36. };
  37.  
  38. box *make_limit_box(box *pp, box *qq, box *rr)
  39. {
  40.   return new limit_box(pp, qq, rr);
  41. }
  42.  
  43. limit_box::limit_box(box *pp, box *qq, box *rr)
  44. : p(pp), from(qq), to(rr)
  45. {
  46.   spacing_type = p->spacing_type;
  47. }
  48.  
  49. limit_box::~limit_box()
  50. {
  51.   delete p;
  52.   delete from;
  53.   delete to;
  54. }
  55.  
  56. int limit_box::compute_metrics(int style)
  57. {
  58.   printf(".nr " SIZE_FORMAT " \\n[.s]\n", uid);
  59.   if (!(style <= SCRIPT_STYLE && one_size_reduction_flag))
  60.     set_script_size();
  61.   printf(".nr " SMALL_SIZE_FORMAT " \\n[.s]\n", uid);
  62.   int res = 0;
  63.   int mark_uid = -1;
  64.   if (from != 0) {
  65.     res = from->compute_metrics(cramped_style(script_style(style)));
  66.     if (res)
  67.       mark_uid = from->uid;
  68.   }
  69.   if (to != 0) {
  70.     int r = to->compute_metrics(script_style(style));
  71.     if (res && r)
  72.       error("multiple marks and lineups");
  73.     else  {
  74.       mark_uid = to->uid;
  75.       res = r;
  76.     }
  77.   }
  78.   printf(".ps \\n[" SIZE_FORMAT "]\n", uid);
  79.   int r = p->compute_metrics(style);
  80.   p->compute_subscript_kern();
  81.   if (res && r)
  82.     error("multiple marks and lineups");
  83.   else {
  84.     mark_uid = p->uid;
  85.     res = r;
  86.   }
  87.   printf(".nr " LEFT_WIDTH_FORMAT " "
  88.      "0\\n[" WIDTH_FORMAT "]",
  89.      uid, p->uid);
  90.   if (from != 0)
  91.     printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
  92.        p->uid, from->uid);
  93.   if (to != 0)
  94.     printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
  95.        p->uid, to->uid);
  96.   printf("/2\n");
  97.   printf(".nr " WIDTH_FORMAT " "
  98.      "0\\n[" WIDTH_FORMAT "]",
  99.      uid, p->uid);
  100.   if (from != 0)
  101.     printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
  102.        p->uid, from->uid);
  103.   if (to != 0)
  104.     printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
  105.        p->uid, to->uid);
  106.   printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid);
  107.   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid);
  108.   if (to != 0)
  109.     printf(">?\\n[" WIDTH_FORMAT "]", to->uid);
  110.   if (from != 0)
  111.     printf(">?\\n[" WIDTH_FORMAT "]", from->uid);
  112.   printf("\n");
  113.   if (res)
  114.     printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]"
  115.        "-(\\n[" WIDTH_FORMAT "]/2))\n",
  116.        uid, mark_uid);
  117.   if (to != 0) {
  118.     printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT
  119.        "]>?%dM+\\n[" HEIGHT_FORMAT "]\n",
  120.        uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid);
  121.     printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
  122.        HEIGHT_FORMAT "]+%dM\n",
  123.        uid, uid, to->uid, big_op_spacing5);
  124.   }
  125.   else
  126.     printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
  127.   if (from != 0) {
  128.     printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT
  129.        "]>?%dM+\\n[" DEPTH_FORMAT "]\n",
  130.        uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid);
  131.     printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
  132.        DEPTH_FORMAT "]+%dM\n",
  133.        uid, uid, from->uid, big_op_spacing5);
  134.   }
  135.   else
  136.     printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
  137.   return res;
  138. }
  139.  
  140. void limit_box::output()
  141. {
  142.   printf("\\s[\\n[" SMALL_SIZE_FORMAT "]]", uid);
  143.   if (to != 0) {
  144.     printf("\\Z" DELIMITER_CHAR);
  145.     printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
  146.     printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
  147.        "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'",
  148.        uid, to->uid, p->uid);
  149.     to->output();
  150.     printf(DELIMITER_CHAR);
  151.   }
  152.   if (from != 0) {
  153.     printf("\\Z" DELIMITER_CHAR);
  154.     printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
  155.     printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
  156.        "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
  157.        uid, p->uid, from->uid);
  158.     from->output();
  159.     printf(DELIMITER_CHAR);
  160.   }
  161.   printf("\\s[\\n[" SIZE_FORMAT "]]", uid);
  162.   printf("\\Z" DELIMITER_CHAR);
  163.   printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
  164.      "-(\\n[" WIDTH_FORMAT "]u/2u)'",
  165.      uid, p->uid);
  166.   p->output();
  167.   printf(DELIMITER_CHAR);
  168.   printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
  169. }
  170.  
  171. void limit_box::debug_print()
  172. {
  173.   fprintf(stderr, "{ ");
  174.   p->debug_print();
  175.   fprintf(stderr, " }");
  176.   if (from) {
  177.     fprintf(stderr, " from { ");
  178.     from->debug_print();
  179.     fprintf(stderr, " }");
  180.   }
  181.   if (to) {
  182.     fprintf(stderr, " to { ");
  183.     to->debug_print();
  184.     fprintf(stderr, " }");
  185.   }
  186. }
  187.  
  188. void limit_box::check_tabs(int level)
  189. {
  190.   if (to)
  191.     to->check_tabs(level + 1);
  192.   if (from)
  193.     from->check_tabs(level + 1);
  194.   p->check_tabs(level + 1);
  195. }
  196.